package cn.com.mjsoft.framework.persistence.core.support.transform;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import cn.com.mjsoft.framework.persistence.core.JdbcInstrument;
import cn.com.mjsoft.framework.persistence.core.RowTransform;
import cn.com.mjsoft.framework.util.ObjectUtility;

public class BeanValueRowTransform implements RowTransform
{
    private Class<?> clazz = null;

    private static Map<String, Map<String, Field>> clazzMap = new HashMap<String, Map<String, Field>>();

    public BeanValueRowTransform()
    {
    }

    public BeanValueRowTransform( Class<?> clazz )
    {
        this.clazz = clazz;
    }

    public Object convertRow( ResultSet rs, int rowNum ) throws SQLException
    {
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();

        Field field = null;

        Object obj = null;

        Map<String, Field> fieldInfoMap = null;

        try
        {
            fieldInfoMap = ( Map<String, Field> ) clazzMap.get( clazz.getName() );

            if( fieldInfoMap == null )
            {
                fieldInfoMap = new HashMap<String, Field>();

                Field[] declaredFields = clazz.getDeclaredFields();

                Field f = null;

                for ( int i = 0; i < declaredFields.length; i++ )
                {
                    f = declaredFields[i];

                    int modifier = f.getModifiers();

                    if( !( ( Modifier.isStatic( modifier ) || Modifier.isFinal( modifier ) ) ) )
                    {
                        fieldInfoMap.put( f.getName(), f );
                    }

                }

                clazzMap.put( clazz.getName(), fieldInfoMap );
            }

            obj = ObjectUtility.buildObject( this.clazz );

            if( obj != null )
            {
                for ( int i = 1; i <= columnCount; i++ )
                {
                    String key = rsmd.getColumnLabel( i );

                    field = ( Field ) fieldInfoMap.get( key );

                    if( field != null )
                    {
                        ObjectUtility.setPrivateFieldValue( field, obj,
                            JdbcInstrument.getResultSetValue( rs, i ) );
                    }
                }
            }
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }

        return obj;
    }
}
